import { Request, Response, NextFunction } from 'express';

/**
 * 内存缓存工具
 */
export class MemoryCache {
  private cache = new Map<string, { data: any; expiry: number }>();
  private defaultTTL = 60000; // 默认60秒

  set(key: string, data: any, ttl: number = this.defaultTTL): void {
    this.cache.set(key, {
      data,
      expiry: Date.now() + ttl
    });
  }

  get(key: string): any | null {
    const item = this.cache.get(key);
    if (!item) return null;
    
    if (Date.now() > item.expiry) {
      this.cache.delete(key);
      return null;
    }
    
    return item.data;
  }

  delete(key: string): boolean {
    return this.cache.delete(key);
  }

  clear(): void {
    this.cache.clear();
  }

  size(): number {
    return this.cache.size;
  }
}

/**
 * 缓存键生成器
 */
export const generateCacheKey = (prefix: string, ...params: any[]): string => {
  const paramString = params.map(param => 
    typeof param === 'object' ? JSON.stringify(param) : String(param)
  ).join(':');
  
  return `${prefix}:${paramString}`;
};

/**
 * 缓存装饰器
 */
export const Cacheable = (ttl: number = 60000, keyPrefix?: string) => {
  return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    const originalMethod = descriptor.value;
    const cache = new MemoryCache();
    
    descriptor.value = async function (...args: any[]) {
      const cacheKey = keyPrefix 
        ? generateCacheKey(keyPrefix, ...args)
        : generateCacheKey(`${target.constructor.name}:${propertyKey}`, ...args);
      
      const cached = cache.get(cacheKey);
      if (cached !== null) {
        return cached;
      }
      
      const result = await originalMethod.apply(this, args);
      cache.set(cacheKey, result, ttl);
      return result;
    };
    
    return descriptor;
  };
};